﻿using System;
using System.Collections.Generic;
using System.Text;

using RaisingStudio.Data.Common.Builders;
using RaisingStudio.Data.Common.Managers;

namespace RaisingStudio.Data.Common.Factories
{
    /// <summary>
    /// DataAdapter factory.
    /// </summary>
    public class DataAdapterFactory
    {
        #region static member
        /// <summary>
        /// Gets database type.
        /// </summary>
        /// <param name="dataAdapter">DataAdapter.</param>
        /// <returns>database type.</returns>
        public static DatabaseType GetDatabaseType(System.Data.IDbDataAdapter dataAdapter)
        {
            if (dataAdapter is System.Data.SqlClient.SqlDataAdapter)
            {
                return DatabaseType.SQL;
            }
            else if (dataAdapter is System.Data.SqlServerCe.SqlCeDataAdapter)
            {
                return DatabaseType.SQLCE;
            }
            else if (dataAdapter is System.Data.OracleClient.OracleDataAdapter)
            {
                return DatabaseType.ORACLE;
            }
            else if (dataAdapter is System.Data.Odbc.OdbcDataAdapter)
            {
                return DatabaseType.ODBC;
            }
            else if (dataAdapter is System.Data.OleDb.OleDbDataAdapter)
            {
                return DatabaseType.OLEDB;
            }
            else
            {
                throw (new System.NotSupportedException("Unknown Type."));
            }
        }
        #endregion
        #region Common property 
        private System.Data.IDbConnection connection;
        /// <summary>
        /// database connection.
        /// </summary>
        public System.Data.IDbConnection Connection
        {
            get
            {
                return this.connection;
            }
        }

        private DatabaseType _databaseType;
        /// <summary>
        /// Database type.
        /// </summary>
        public DatabaseType DatabaseType
        {
            get
            {
                return this._databaseType;
            }
            set
            {
                this._databaseType = value;
            }
        }

        private string _providerName;
        /// <summary>
        /// The name of provider.
        /// </summary>
        public string ProviderName
        {
            get
            {
                return this._providerName;
            }
            set
            {
                this._providerName = value;
            }
        }

        #region
        private bool systemCommandBuilder = false;
        /// <summary>
        /// Use System Command builder.
        /// </summary>
        public bool SystemCommandBuilder
        {
            get
            {
                return this.systemCommandBuilder;
            }
            set
            {
                this.systemCommandBuilder = value;
            }
        }

        private bool checkConcurrency = false;
        /// <summary>
        /// Check concurrency.
        /// </summary>
        public bool CheckConcurrency
        {
            get
            {
                return this.checkConcurrency;
            }
            set
            {
                this.checkConcurrency = value;
            }
        }
        #endregion
        #endregion
        #region Constructor
        /// <summary>
        /// Constructor
        /// </summary>
        public DataAdapterFactory()
        {
            this.connection = ConnectionFactory.CreateConnection();

            DatabaseType databaseType;
            string providerName;
            ConnectionFactory.GetConnectionSetting(out databaseType, out providerName);
            this._databaseType = databaseType;
            this._providerName = providerName;
        }

        public DataAdapterFactory(System.Data.IDbConnection connection)
        {
            this.connection = connection;
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="connection">database connection.</param>
        public DataAdapterFactory(System.Data.IDbConnection connection, DatabaseType databaseType, string providerName)
        {
            this.connection = connection;
            this._databaseType = databaseType;
            this._providerName = providerName;
        }
        #endregion

        #region Create 空adapter 
        /// <summary>
        /// Create an empty DataAdapter.
        /// </summary>
        /// <param name="databaseType">database type.</param>
        /// <returns>An empty DataAdapter.</returns>
        public virtual System.Data.IDbDataAdapter CreateEmptyDataAdapter(DatabaseType databaseType)
        {
            switch (databaseType)
            {
                case DatabaseType.SQL:
                    {
                        return new System.Data.SqlClient.SqlDataAdapter();
                    }
                case DatabaseType.SQLCE:
                    {
                        return new System.Data.SqlServerCe.SqlCeDataAdapter();
                    }
                case DatabaseType.ORACLE:
                    {
                        return new System.Data.OracleClient.OracleDataAdapter();
                    }
                case DatabaseType.ODBC:
                    {
                        return new System.Data.Odbc.OdbcDataAdapter();
                    }
                case DatabaseType.OLEDB:
                    {
                        return new System.Data.OleDb.OleDbDataAdapter();
                    }
                case DatabaseType.SHAREPOINT:
                    {
                        return new System.Data.SharePoint.SharePointDataAdapter();
                    }
                default:
                    {
                        throw (new System.NotSupportedException("Unknown Type."));
                    }
            }
        }

        /// <summary>
        /// Create an empty DataAdapter.
        /// </summary>
        /// <returns>An empty DataAdapter.</returns>
        public virtual System.Data.IDbDataAdapter CreateEmptyDataAdapter()
        {
            if (this._databaseType == DatabaseType.OTHER)
            {
                System.Data.IDbDataAdapter dataAdapter = ProviderManager.Instance.CreateDataAdapter(this._providerName);
                if (dataAdapter == null)
                {
                    DatabaseType databaseType = ConnectionFactory.GetDatabaseType(this.connection);
                    dataAdapter = CreateEmptyDataAdapter(databaseType);
                }
                return dataAdapter;
            }
            else
            {
                return CreateEmptyDataAdapter(this._databaseType);
            }
        }
        #endregion
        #region Create Command
        /// <summary>
        /// Create a command builder.
        /// </summary>
        /// <param name="databaseType">database type.</param>
        /// <param name="dataAdapter">DataAdapter.</param>
        /// <returns>Command builder.</returns>
        protected virtual object CreateDbCommandBuilder(DatabaseType databaseType, System.Data.IDbDataAdapter dataAdapter)
        {
             switch (databaseType)
            {
                case DatabaseType.SQL:
                    {
                        return new System.Data.SqlClient.SqlCommandBuilder(dataAdapter as System.Data.SqlClient.SqlDataAdapter);
                    }
                case DatabaseType.SQLCE:
                    {
                        return new System.Data.SqlServerCe.SqlCeCommandBuilder(dataAdapter as System.Data.SqlServerCe.SqlCeDataAdapter);
                    }
                case DatabaseType.ORACLE:
                    {
                        return new System.Data.OracleClient.OracleCommandBuilder(dataAdapter as System.Data.OracleClient.OracleDataAdapter);
                    }
                case DatabaseType.ODBC:
                    {
                        return new System.Data.Odbc.OdbcCommandBuilder(dataAdapter as System.Data.Odbc.OdbcDataAdapter);
                    }
                case DatabaseType.OLEDB:
                    {
                        return new System.Data.OleDb.OleDbCommandBuilder(dataAdapter as System.Data.OleDb.OleDbDataAdapter);
                    }
                default:
                    {
                        throw (new System.NotSupportedException("Unknown Type."));
                    }
            }
       }
                
        /// <summary>
       /// Create a command builder.
        /// </summary>
       /// <param name="dataAdapter">DataAdapter.</param>
       /// <returns>Command builder.</returns>
        protected virtual object CreateDbCommandBuilder(System.Data.IDbDataAdapter dataAdapter)
        {
            if (this._databaseType == DatabaseType.OTHER)
            {
                object commandBuilder = ProviderManager.Instance.CreateCommandBuilder(this._providerName, dataAdapter);
                if (commandBuilder == null)
                {
                    DatabaseType databaseType = ConnectionFactory.GetDatabaseType(this.connection);
                    commandBuilder = CreateDbCommandBuilder(databaseType, dataAdapter);
                }
                return commandBuilder;
            }
            else
            {
                return CreateDbCommandBuilder(this._databaseType, dataAdapter);
            }
        }
        #endregion
        #region Sets DataAdapter Command 
        /// <summary>
        /// Sets DataAdapter Command.
        /// </summary>
        /// <param name="dataAdapter">DataAdapter.</param>
        /// <param name="commandBuilder">Command builder.</param>
        /// <param name="checkConcurrency">Check concurrency.</param>
        private void SetDataAdapterCommandInternal(ref System.Data.IDbDataAdapter dataAdapter, CommandBuilder commandBuilder, bool checkConcurrency)
        {
            if (this.systemCommandBuilder)
            {
                SetDataAdapterCommand(ref dataAdapter);
            }
            else
            {
                SetDataAdapterCommand(ref dataAdapter, commandBuilder, checkConcurrency);
            }
        }

        /// <summary>
        /// Sets DataAdapter Command.
        /// </summary>
        /// <param name="dataAdapter">DataAdapter.</param>
        /// <param name="commandBuilder">Command builder.</param>
        protected virtual void SetDataAdapterCommand(ref System.Data.IDbDataAdapter dataAdapter, CommandBuilder commandBuilder)
        {
            SetDataAdapterCommand(ref dataAdapter, commandBuilder, this.checkConcurrency);
        }

        /// <summary>
        /// Sets DataAdapter Command.
        /// </summary>
        /// <param name="dataAdapter">DataAdapter.</param>
        /// <param name="commandBuilder">Command builder.</param>
        /// <param name="checkConcurrency">Check concurrency.</param>
        protected virtual void SetDataAdapterCommand(ref System.Data.IDbDataAdapter dataAdapter, CommandBuilder commandBuilder, bool checkConcurrency)
        {
            dataAdapter.DeleteCommand = commandBuilder.GetDeleteCommand(((dataAdapter as System.Data.IDataAdapter).TableMappings as System.Data.Common.DataTableMappingCollection)[0], checkConcurrency);
            dataAdapter.InsertCommand = commandBuilder.GetInsertCommand(((dataAdapter as System.Data.IDataAdapter).TableMappings as System.Data.Common.DataTableMappingCollection)[0]);
            dataAdapter.UpdateCommand = commandBuilder.GetUpdateCommand(((dataAdapter as System.Data.IDataAdapter).TableMappings as System.Data.Common.DataTableMappingCollection)[0], false, checkConcurrency);
        }

        /// <summary>
        /// Sets DataAdapter Command.
        /// </summary>
        /// <param name="dataAdapter">DataAdapter.</param>
        /// <param name="commandBuilder">Command builder.</param>
        protected virtual void SetDataAdapterCommand(ref System.Data.IDbDataAdapter dataAdapter, object commandBuilder)
        {
            // TODO: 2009-02-24 get commands from commandbuilder.
            /*
            dataAdapter.DeleteCommand = commandBuilder.GetDeleteCommand();
            dataAdapter.InsertCommand = commandBuilder.GetInsertCommand();
            dataAdapter.UpdateCommand = commandBuilder.GetUpdateCommand();
             */
        }

        /// <summary>
        /// Sets DataAdapter Command.
        /// </summary>
        /// <param name="dataAdapter">DataAdapter.</param>
        protected virtual void SetDataAdapterCommand(ref System.Data.IDbDataAdapter dataAdapter)
        {
            object commandBuilder = CreateDbCommandBuilder(dataAdapter);
            SetDataAdapterCommand(ref dataAdapter, commandBuilder);
        }
        #endregion
        #region Create adapter 
        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type)
        {
            return CreateDataAdapter(type, true, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string[] columnNames)
        {
            return CreateDataAdapter(type, columnNames, true, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, object[] primaryKeys)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetConditionSelectCommand(out dataTableMapping);
            for (int i = 0; i < dataAdapter.SelectCommand.Parameters.Count; i++)
            {
                (dataAdapter.SelectCommand.Parameters[i] as System.Data.IDbDataParameter).Value = primaryKeys[i];
            }
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            return dataAdapter;
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, object[] primaryKeys, string[] columnNames)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetConditionSelectCommand(columnNames, out dataTableMapping);
            for (int i = 0; i < dataAdapter.SelectCommand.Parameters.Count; i++)
            {
                (dataAdapter.SelectCommand.Parameters[i] as System.Data.IDbDataParameter).Value = primaryKeys[i];
            }
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            return dataAdapter;
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, CommonCommand conditionCommand)
        {
            return CreateDataAdapter(type, conditionCommand, true, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string[] columnNames, CommonCommand conditionCommand)
        {
            return CreateDataAdapter(type, columnNames, conditionCommand, true, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, bool update)
        {
            return CreateDataAdapter(type, update, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string[] columnNames, bool update)
        {
            return CreateDataAdapter(type, columnNames, update, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, CommonCommand conditionCommand, bool update)
        {
            return CreateDataAdapter(type, conditionCommand, update, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string[] columnNames, CommonCommand conditionCommand, bool update)
        {
            return CreateDataAdapter(type, columnNames, conditionCommand, update, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, bool update, bool checkConcurrency)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetSelectCommand(out dataTableMapping);
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            if (update)
            {
                SetDataAdapterCommandInternal(ref dataAdapter, commandBuilder, checkConcurrency);
            }
            return dataAdapter;
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string[] columnNames, bool update, bool checkConcurrency)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetSelectCommand(columnNames, out dataTableMapping);
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            if (update)
            {
                SetDataAdapterCommandInternal(ref dataAdapter, commandBuilder, checkConcurrency);
            }
            return dataAdapter;
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, CommonCommand conditionCommand, bool update, bool checkConcurrency)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetSelectCommand(conditionCommand, out dataTableMapping);
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            if (update)
            {
                SetDataAdapterCommandInternal(ref dataAdapter, commandBuilder, checkConcurrency);
            }
            return dataAdapter;
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string[] columnNames, CommonCommand conditionCommand, bool update, bool checkConcurrency)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetSelectCommand(columnNames, conditionCommand, out dataTableMapping);
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            if (update)
            {
                SetDataAdapterCommandInternal(ref dataAdapter, commandBuilder, checkConcurrency);
            }
            return dataAdapter;
        }


        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string name)
        {
            return CreateDataAdapter(type, name, true, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string name, string[] columnNames)
        {
            return CreateDataAdapter(type, name, columnNames, true, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string name, object[] primaryKeys)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type, name);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetConditionSelectCommand(out dataTableMapping);
            for (int i = 0; i < dataAdapter.SelectCommand.Parameters.Count; i++)
            {
                (dataAdapter.SelectCommand.Parameters[i] as System.Data.IDbDataParameter).Value = primaryKeys[i];
            }
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            return dataAdapter;
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="primaryKeys">The value of primary key.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string name, object[] primaryKeys, string[] columnNames)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type, name);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetConditionSelectCommand(columnNames, out dataTableMapping);
            for (int i = 0; i < dataAdapter.SelectCommand.Parameters.Count; i++)
            {
                (dataAdapter.SelectCommand.Parameters[i] as System.Data.IDbDataParameter).Value = primaryKeys[i];
            }
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            return dataAdapter;
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string name, CommonCommand conditionCommand)
        {
            return CreateDataAdapter(type, name, conditionCommand, true, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string name, string[] columnNames, CommonCommand conditionCommand)
        {
            return CreateDataAdapter(type, name, columnNames, conditionCommand, true, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string name, bool update)
        {
            return CreateDataAdapter(type, name, update, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string name, string[] columnNames, bool update)
        {
            return CreateDataAdapter(type, name, columnNames, update, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string name, CommonCommand conditionCommand, bool update)
        {
            return CreateDataAdapter(type, name, conditionCommand, update, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string name, string[] columnNames, CommonCommand conditionCommand, bool update)
        {
            return CreateDataAdapter(type, name, columnNames, conditionCommand, update, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string name, bool update, bool checkConcurrency)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type, name);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetSelectCommand(out dataTableMapping);
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            if (update)
            {
                SetDataAdapterCommandInternal(ref dataAdapter, commandBuilder, checkConcurrency);
            }
            return dataAdapter;
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string name, string[] columnNames, bool update, bool checkConcurrency)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type, name);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetSelectCommand(columnNames, out dataTableMapping);
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            if (update)
            {
                SetDataAdapterCommandInternal(ref dataAdapter, commandBuilder, checkConcurrency);
            }
            return dataAdapter;
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string name, CommonCommand conditionCommand, bool update, bool checkConcurrency)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type, name);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetSelectCommand(conditionCommand, out dataTableMapping);
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            if (update)
            {
                SetDataAdapterCommandInternal(ref dataAdapter, commandBuilder, checkConcurrency);
            }
            return dataAdapter;
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(Type type, string name, string[] columnNames, CommonCommand conditionCommand, bool update, bool checkConcurrency)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type, name);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetSelectCommand(columnNames, conditionCommand, out dataTableMapping);
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            if (update)
            {
                SetDataAdapterCommandInternal(ref dataAdapter, commandBuilder, checkConcurrency);
            }
            return dataAdapter;
        }

        #region 自definition adapter 
        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="selectCommand">Select command.</param>
        /// <returns>DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(CommonCommand selectCommand)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            dataAdapter.SelectCommand = ConvertCommand(selectCommand);
            return dataAdapter;
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="selectCommand">Select command.</param>
        /// <param name="insertCommand">Insert command.</param>
        /// <param name="updateCommand">Update command.</param>
        /// <param name="deleteCommand">Delete command.</param>
        /// <returns>DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateDataAdapter(CommonCommand selectCommand, CommonCommand insertCommand, CommonCommand updateCommand, CommonCommand deleteCommand)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            if (selectCommand != null)
            {
                dataAdapter.SelectCommand = ConvertCommand(selectCommand);
            }
            if (insertCommand != null)
            {
                dataAdapter.InsertCommand = ConvertCommand(insertCommand);
            }
            if (updateCommand != null)
            {
                dataAdapter.UpdateCommand = ConvertCommand(updateCommand);
            }
            if (deleteCommand != null)
            {
                dataAdapter.DeleteCommand = ConvertCommand(deleteCommand);
            }
            return dataAdapter;
        }
        #endregion

        #region View Mode
        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateViewDataAdapter(Type type, CommonCommand conditionCommand)
        {
            return CreateViewDataAdapter(type, conditionCommand, true, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateViewDataAdapter(Type type, string[] columnNames, CommonCommand conditionCommand)
        {
            return CreateViewDataAdapter(type, columnNames, conditionCommand, true, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateViewDataAdapter(Type type, CommonCommand conditionCommand, bool update)
        {
            return CreateViewDataAdapter(type, conditionCommand, update, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateViewDataAdapter(Type type, string[] columnNames, CommonCommand conditionCommand, bool update)
        {
            return CreateViewDataAdapter(type, columnNames, conditionCommand, update, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateViewDataAdapter(Type type, CommonCommand conditionCommand, bool update, bool checkConcurrency)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetViewSelectCommand(conditionCommand, out dataTableMapping);
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            if (update)
            {
                SetDataAdapterCommandInternal(ref dataAdapter, commandBuilder, checkConcurrency);
            }
            return dataAdapter;
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateViewDataAdapter(Type type, string[] columnNames, CommonCommand conditionCommand, bool update, bool checkConcurrency)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetViewSelectCommand(columnNames, conditionCommand, out dataTableMapping);
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            if (update)
            {
                SetDataAdapterCommandInternal(ref dataAdapter, commandBuilder, checkConcurrency);
            }
            return dataAdapter;
        }


        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateViewDataAdapter(Type type, string name, CommonCommand conditionCommand)
        {
            return CreateViewDataAdapter(type, name, conditionCommand, true, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateViewDataAdapter(Type type, string name, string[] columnNames, CommonCommand conditionCommand)
        {
            return CreateViewDataAdapter(type, name, columnNames, conditionCommand, true, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateViewDataAdapter(Type type, string name, CommonCommand conditionCommand, bool update)
        {
            return CreateViewDataAdapter(type, name, conditionCommand, update, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateViewDataAdapter(Type type, string name, string[] columnNames, CommonCommand conditionCommand, bool update)
        {
            return CreateViewDataAdapter(type, name, columnNames, conditionCommand, update, this.checkConcurrency);
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateViewDataAdapter(Type type, string name, CommonCommand conditionCommand, bool update, bool checkConcurrency)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type, name);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetViewSelectCommand(conditionCommand, out dataTableMapping);
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            if (update)
            {
                SetDataAdapterCommandInternal(ref dataAdapter, commandBuilder, checkConcurrency);
            }
            return dataAdapter;
        }

        /// <summary>
        /// Create DataAdapter.
        /// </summary>
        /// <param name="type">Type of data object.</param>
        /// <param name="name">Data object name.</param>
        /// <param name="columnNames">An array of Columns.</param>
        /// <param name="conditionCommand">Condition Command.</param>
        /// <returns>The Data object DataAdapter.</returns>
        public System.Data.IDbDataAdapter CreateViewDataAdapter(Type type, string name, string[] columnNames, CommonCommand conditionCommand, bool update, bool checkConcurrency)
        {
            System.Data.IDbDataAdapter dataAdapter = CreateEmptyDataAdapter();
            CommandBuilder commandBuilder = CreateCommandBuilder(type, name);
            System.Data.Common.DataTableMapping dataTableMapping;
            dataAdapter.SelectCommand = commandBuilder.GetViewSelectCommand(columnNames, conditionCommand, out dataTableMapping);
            (dataAdapter as System.Data.IDataAdapter).TableMappings.Add(dataTableMapping);
            if (update)
            {
                SetDataAdapterCommandInternal(ref dataAdapter, commandBuilder, checkConcurrency);
            }
            return dataAdapter;
        }
        #endregion
        #endregion

        public virtual DatabaseType GetDatabaseType()
        {
            if ((this._databaseType == DatabaseType.OTHER) && (!ProviderManager.Instance.ProviderExists(this._providerName)))
            {
                DatabaseType databaseType = ConnectionFactory.GetDatabaseType(this.connection);
                return databaseType;
            }
            return this._databaseType;
        }

        protected virtual CommandBuilder CreateCommandBuilder(Type type)
        {
            DatabaseType databaseType = GetDatabaseType();
#if !(PocketPC || Smartphone || WindowsCE)
            if (databaseType == DatabaseType.SHAREPOINT)
            {
                return new SharePointCommandBuilder(this.connection, databaseType, this._providerName, type);
            }
            else
            {
#endif
                return new CommandBuilder(this.connection, databaseType, this._providerName, type);
#if !(PocketPC || Smartphone || WindowsCE)
            }
#endif
        }

        private CommandBuilder CreateCommandBuilder(Type type, string name)
        {
            DatabaseType databaseType = GetDatabaseType();
#if !(PocketPC || Smartphone || WindowsCE)
            if (databaseType == DatabaseType.SHAREPOINT)
            {
                return new SharePointCommandBuilder(this.connection, databaseType, this._providerName, type, name);
            }
            else
            {
#endif
                return new CommandBuilder(this.connection, databaseType, this._providerName, type, name);
#if !(PocketPC || Smartphone || WindowsCE)
            }
#endif
        }

        protected virtual System.Data.IDbCommand ConvertCommand(CommonCommand commonCommand)
        {
            DatabaseType databaseType = GetDatabaseType();
            return CommandConverter.Convert(commonCommand, this.connection, databaseType, this._providerName);
        }
    }
}
